import { jsonToToml, validateTomlOutput, getConversionStats } from './converter'
import { validateJson } from './validator'

// 测试用例接口
interface TestCase {
  name: string
  description: string
  input: string
  addWindowsEnv?: boolean
  expectedSuccess?: boolean
  expectedErrorType?: string
  skip?: boolean
}

// 测试结果接口
interface TestResult {
  name: string
  description: string
  passed: boolean
  error?: string
  details?: Record<string, unknown>
  performance?: {
    parseTime: number
    convertTime: number
    totalTime: number
  }
}

// 测试套件
export class McpConfigTester {
  private results: TestResult[] = []
  private verbose: boolean

  constructor(verbose: boolean = false) {
    this.verbose = verbose
  }

  // 运行所有测试
  async runAllTests(): Promise<TestResult[]> {
    this.results = []

    if (this.verbose) {
      console.log('开始运行MCP配置测试套件...')
    }

    // 基础功能测试
    await this.runBasicTests()

    // 错误处理测试
    await this.runErrorHandlingTests()

    // 边界条件测试
    await this.runBoundaryTests()

    // 性能测试
    await this.runPerformanceTests()

    // 兼容性测试
    await this.runCompatibilityTests()

    if (this.verbose) {
      this.printResults()
    }

    return this.results
  }

  // 基础功能测试
  private async runBasicTests(): Promise<void> {
    const basicTests: TestCase[] = [
      {
        name: '简单GitHub服务器配置',
        description: '测试基本的GitHub MCP服务器配置转换',
        input: JSON.stringify(
          {
            mcpServers: {
              github: {
                command: 'npx',
                args: ['-y', '@modelcontextprotocol/server-github'],
                env: {
                  GITHUB_PERSONAL_ACCESS_TOKEN: 'your_token_here',
                },
              },
            },
          },
          null,
          2,
        ),
      },
      {
        name: '多服务器配置',
        description: '测试包含多个MCP服务器的配置',
        input: JSON.stringify(
          {
            mcpServers: {
              github: {
                command: 'npx',
                args: ['-y', '@modelcontextprotocol/server-github'],
                env: {
                  GITHUB_PERSONAL_ACCESS_TOKEN: 'your_token_here',
                },
              },
              filesystem: {
                command: 'npx',
                args: ['-y', '@modelcontextprotocol/server-filesystem', '/path/to/files'],
              },
            },
          },
          null,
          2,
        ),
      },
      {
        name: '带Windows环境变量',
        description: '测试添加Windows环境变量的功能',
        input: JSON.stringify(
          {
            mcpServers: {
              test: {
                command: 'node',
                args: ['server.js'],
              },
            },
          },
          null,
          2,
        ),
        addWindowsEnv: true,
      },
      {
        name: '复杂配置结构',
        description: '测试包含resources、tools和prompts的复杂配置',
        input: JSON.stringify(
          {
            mcpServers: {
              example: {
                command: 'npx',
                args: ['-y', '@example/server'],
              },
            },
            resources: [
              {
                uri: 'file:///path/to/file.txt',
                name: 'Example File',
                mimeType: 'text/plain',
              },
            ],
            tools: [
              {
                name: 'example_tool',
                description: 'An example tool',
                inputSchema: {
                  type: 'object',
                  properties: {
                    query: { type: 'string' },
                  },
                },
              },
            ],
          },
          null,
          2,
        ),
      },
    ]

    for (const test of basicTests) {
      await this.runTest(test)
    }
  }

  // 错误处理测试
  private async runErrorHandlingTests(): Promise<void> {
    const errorTests: TestCase[] = [
      {
        name: '无效JSON语法',
        description: '测试无效JSON语法的错误处理',
        input: '{ "mcpServers": { "test": { "command": "node", "args": ["server.js"] }',
        expectedSuccess: false,
        expectedErrorType: 'conversion',
      },
      {
        name: '无效MCP结构',
        description: '测试无效MCP配置结构的错误处理',
        input: JSON.stringify({
          mcpServers: 'invalid', // 应该是对象
        }),
        expectedSuccess: false,
        expectedErrorType: 'structure',
      },
      {
        name: '空配置',
        description: '测试空配置的处理',
        input: '{}',
        expectedSuccess: true,
      },
      {
        name: '非对象配置',
        description: '测试非对象类型的配置',
        input: '"invalid"',
        expectedSuccess: false,
        expectedErrorType: 'conversion',
      },
    ]

    for (const test of errorTests) {
      await this.runTest(test)
    }
  }

  // 边界条件测试
  private async runBoundaryTests(): Promise<void> {
    const boundaryTests: TestCase[] = [
      {
        name: '大型配置',
        description: '测试大型配置文件的处理',
        input: this.generateLargeConfig(),
        expectedSuccess: true,
      },
      {
        name: '特殊字符',
        description: '测试包含特殊字符的配置',
        input: JSON.stringify(
          {
            mcpServers: {
              test: {
                command: 'node',
                args: ['server.js', '--path', 'C:\\Users\\用户\\文件'],
                env: {
                  SPECIAL_KEY: 'Special "value" with \n newlines and \t tabs',
                  UNICODE_测试: '测试值',
                },
              },
            },
          },
          null,
          2,
        ),
        expectedSuccess: true,
      },
      {
        name: '嵌套结构',
        description: '测试深度嵌套的配置结构',
        input: JSON.stringify(
          {
            mcpServers: {
              test: {
                command: 'node',
                env: {
                  NESTED: {
                    deep: {
                      value: 'test',
                    },
                  },
                },
              },
            },
          },
          null,
          2,
        ),
        expectedSuccess: true,
      },
    ]

    for (const test of boundaryTests) {
      await this.runTest(test)
    }
  }

  // 性能测试
  private async runPerformanceTests(): Promise<void> {
    const performanceTests: TestCase[] = [
      {
        name: '性能测试-小型配置',
        description: '测试小型配置的转换性能',
        input: JSON.stringify(
          {
            mcpServers: {
              test: {
                command: 'node',
                args: ['server.js'],
              },
            },
          },
          null,
          2,
        ),
        expectedSuccess: true,
      },
      {
        name: '性能测试-中型配置',
        description: '测试中型配置的转换性能',
        input: this.generateMediumConfig(),
        expectedSuccess: true,
      },
    ]

    for (const test of performanceTests) {
      await this.runTestWithPerformance(test)
    }
  }

  // 兼容性测试
  private async runCompatibilityTests(): Promise<void> {
    const compatibilityTests: TestCase[] = [
      {
        name: 'Claude Desktop配置',
        description: '测试Claude Desktop格式的配置',
        input: JSON.stringify(
          {
            mcpServers: {
              filesystem: {
                command: 'npx',
                args: ['-y', '@modelcontextprotocol/server-filesystem', '/Users/claude/Desktop'],
              },
            },
          },
          null,
          2,
        ),
        expectedSuccess: true,
      },
      {
        name: '单个MCP配置',
        description: '测试单个MCP服务器配置格式',
        input: JSON.stringify(
          {
            type: 'stdio',
            command: 'npx',
            args: ['-y', '@modelcontextprotocol/server-filesystem'],
            env: {
              FILESYSTEM_PATH: '/path/to/files',
            },
          },
          null,
          2,
        ),
        expectedSuccess: true,
      },
    ]

    for (const test of compatibilityTests) {
      await this.runTest(test)
    }
  }

  // 运行单个测试
  private async runTest(testCase: TestCase): Promise<void> {
    if (testCase.skip) {
      if (this.verbose) {
        console.log(`跳过测试: ${testCase.name}`)
      }
      return
    }

    const startTime = performance.now()
    const result: TestResult = {
      name: testCase.name,
      description: testCase.description,
      passed: false,
    }

    try {
      // 验证JSON
      const validationResult = validateJson(testCase.input)
      if (!validationResult.isValid) {
        if (testCase.expectedSuccess === false) {
          result.passed = true
          result.details = { expectedError: true, actualError: validationResult.error }
        } else {
          result.error = `JSON验证失败: ${validationResult.error?.message}`
        }
      } else {
        // 转换为TOML
        const conversionResult = jsonToToml(
          testCase.input,
          testCase.addWindowsEnv || false,
          'windows',
        )

        if (conversionResult.success) {
          if (testCase.expectedSuccess === false) {
            result.error = '预期转换失败，但实际成功了'
          } else {
            // 验证TOML输出
            const tomlValidation = validateTomlOutput(conversionResult.toml || '')
            if (!tomlValidation.isValid) {
              result.error = `TOML验证失败: ${tomlValidation.error}`
            } else {
              result.passed = true
              result.details = {
                tomlLength: conversionResult.toml?.length,
                stats: getConversionStats(testCase.input, conversionResult.toml || ''),
              }
            }
          }
        } else {
          if (testCase.expectedSuccess === false) {
            if (
              testCase.expectedErrorType &&
              conversionResult.error?.type !== testCase.expectedErrorType
            ) {
              result.error = `错误类型不匹配，预期: ${testCase.expectedErrorType}, 实际: ${conversionResult.error?.type}`
            } else {
              result.passed = true
              result.details = { expectedError: true, actualError: conversionResult.error }
            }
          } else {
            result.error = `转换失败: ${conversionResult.error?.message}`
          }
        }
      }
    } catch (error) {
      result.error = `测试异常: ${error instanceof Error ? error.message : '未知错误'}`
    }

    const endTime = performance.now()
    result.performance = {
      parseTime: 0, // 这里可以添加更详细的性能测量
      convertTime: endTime - startTime,
      totalTime: endTime - startTime,
    }

    this.results.push(result)

    if (this.verbose) {
      console.log(
        `${result.passed ? '✅' : '❌'} ${testCase.name}: ${result.passed ? '通过' : result.error}`,
      )
      if (result.details) {
        console.log(`  详情:`, result.details)
      }
    }
  }

  // 运行带性能测量的测试
  private async runTestWithPerformance(testCase: TestCase): Promise<void> {
    const result = await this.runTestWithDetails(testCase)
    this.results.push(result)

    if (this.verbose) {
      console.log(
        `${result.passed ? '✅' : '❌'} ${testCase.name}: ${result.passed ? '通过' : result.error}`,
      )
      if (result.performance) {
        console.log(
          `  性能: 解析 ${result.performance.parseTime.toFixed(2)}ms, 转换 ${result.performance.convertTime.toFixed(2)}ms`,
        )
      }
    }
  }

  // 运行带详细信息的测试
  private async runTestWithDetails(testCase: TestCase): Promise<TestResult> {
    const startTime = performance.now()
    const result: TestResult = {
      name: testCase.name,
      description: testCase.description,
      passed: false,
    }

    try {
      // 测量JSON解析时间
      const parseStartTime = performance.now()
      const validationResult = validateJson(testCase.input)
      const parseEndTime = performance.now()

      if (!validationResult.isValid) {
        if (testCase.expectedSuccess === false) {
          result.passed = true
          result.details = { expectedError: true, actualError: validationResult.error }
        } else {
          result.error = `JSON验证失败: ${validationResult.error?.message}`
        }
      } else {
        // 测量转换时间
        const convertStartTime = performance.now()
        const conversionResult = jsonToToml(
          testCase.input,
          testCase.addWindowsEnv || false,
          'windows',
        )
        const convertEndTime = performance.now()

        if (conversionResult.success) {
          if (testCase.expectedSuccess === false) {
            result.error = '预期转换失败，但实际成功了'
          } else {
            // 验证TOML输出
            const tomlValidation = validateTomlOutput(conversionResult.toml || '')
            if (!tomlValidation.isValid) {
              result.error = `TOML验证失败: ${tomlValidation.error}`
            } else {
              result.passed = true
              result.details = {
                tomlLength: conversionResult.toml?.length,
                stats: getConversionStats(testCase.input, conversionResult.toml || ''),
              }
            }
          }
        } else {
          if (testCase.expectedSuccess === false) {
            if (
              testCase.expectedErrorType &&
              conversionResult.error?.type !== testCase.expectedErrorType
            ) {
              result.error = `错误类型不匹配，预期: ${testCase.expectedErrorType}, 实际: ${conversionResult.error?.type}`
            } else {
              result.passed = true
              result.details = { expectedError: true, actualError: conversionResult.error }
            }
          } else {
            result.error = `转换失败: ${conversionResult.error?.message}`
          }
        }

        result.performance = {
          parseTime: parseEndTime - parseStartTime,
          convertTime: convertEndTime - convertStartTime,
          totalTime: performance.now() - startTime,
        }
      }
    } catch (error) {
      result.error = `测试异常: ${error instanceof Error ? error.message : '未知错误'}`
      result.performance = {
        parseTime: 0,
        convertTime: 0,
        totalTime: performance.now() - startTime,
      }
    }

    return result
  }

  // 生成大型配置
  private generateLargeConfig(): string {
    const mcpServers: Record<string, unknown> = {}

    // 生成100个服务器配置
    for (let i = 0; i < 100; i++) {
      mcpServers[`server_${i}`] = {
        command: 'npx',
        args: ['-y', `@example/server-${i}`],
        env: {
          [`SERVER_ID_${i}`]: `server_${i}`,
          [`SERVER_PATH_${i}`]: `/path/to/server_${i}`,
        },
      }
    }

    return JSON.stringify({ mcpServers }, null, 2)
  }

  // 生成中型配置
  private generateMediumConfig(): string {
    const mcpServers: Record<string, unknown> = {}
    const resources: Record<string, unknown>[] = []
    const tools: Record<string, unknown>[] = []

    // 生成20个服务器配置
    for (let i = 0; i < 20; i++) {
      mcpServers[`server_${i}`] = {
        command: 'npx',
        args: ['-y', `@example/server-${i}`],
        env: {
          [`SERVER_ID_${i}`]: `server_${i}`,
        },
      }
    }

    // 生成50个资源
    for (let i = 0; i < 50; i++) {
      resources.push({
        uri: `file:///path/to/resource_${i}.txt`,
        name: `Resource ${i}`,
        mimeType: 'text/plain',
      })
    }

    // 生成30个工具
    for (let i = 0; i < 30; i++) {
      tools.push({
        name: `tool_${i}`,
        description: `Tool number ${i}`,
        inputSchema: {
          type: 'object',
          properties: {
            [`param_${i}`]: { type: 'string' },
          },
        },
      })
    }

    return JSON.stringify({ mcpServers, resources, tools }, null, 2)
  }

  // 打印测试结果
  private printResults(): void {
    const passed = this.results.filter((r) => r.passed).length
    const total = this.results.length
    const failed = total - passed

    console.log(`\n测试结果: ${passed}/${total} 通过, ${failed} 失败`)

    if (failed > 0) {
      console.log('\n失败的测试:')
      this.results
        .filter((r) => !r.passed)
        .forEach((result) => {
          console.log(`  ❌ ${result.name}: ${result.error}`)
        })
    }

    // 性能统计
    const performanceResults = this.results.filter((r) => r.performance)
    if (performanceResults.length > 0) {
      const avgParseTime =
        performanceResults.reduce((sum, r) => sum + (r.performance?.parseTime || 0), 0) /
        performanceResults.length
      const avgConvertTime =
        performanceResults.reduce((sum, r) => sum + (r.performance?.convertTime || 0), 0) /
        performanceResults.length
      const avgTotalTime =
        performanceResults.reduce((sum, r) => sum + (r.performance?.totalTime || 0), 0) /
        performanceResults.length

      console.log('\n性能统计:')
      console.log(`  平均解析时间: ${avgParseTime.toFixed(2)}ms`)
      console.log(`  平均转换时间: ${avgConvertTime.toFixed(2)}ms`)
      console.log(`  平均总时间: ${avgTotalTime.toFixed(2)}ms`)
    }
  }

  // 获取测试结果摘要
  getResultsSummary(): {
    total: number
    passed: number
    failed: number
    passRate: number
    avgPerformance: {
      parseTime: number
      convertTime: number
      totalTime: number
    } | null
  } {
    const total = this.results.length
    const passed = this.results.filter((r) => r.passed).length
    const failed = total - passed
    const passRate = total > 0 ? (passed / total) * 100 : 0

    const performanceResults = this.results.filter((r) => r.performance)
    let avgPerformance = null

    if (performanceResults.length > 0) {
      avgPerformance = {
        parseTime:
          performanceResults.reduce((sum, r) => sum + (r.performance?.parseTime || 0), 0) /
          performanceResults.length,
        convertTime:
          performanceResults.reduce((sum, r) => sum + (r.performance?.convertTime || 0), 0) /
          performanceResults.length,
        totalTime:
          performanceResults.reduce((sum, r) => sum + (r.performance?.totalTime || 0), 0) /
          performanceResults.length,
      }
    }

    return {
      total,
      passed,
      failed,
      passRate,
      avgPerformance,
    }
  }

  // 获取详细的测试结果
  getDetailedResults(): TestResult[] {
    return [...this.results]
  }
}

// 快速测试函数，用于在组件中调用
export async function quickMcpConfigTest(): Promise<{
  success: boolean
  message: string
  details?: Record<string, unknown>
}> {
  try {
    const tester = new McpConfigTester(false)
    await tester.runAllTests()
    const summary = tester.getResultsSummary()

    if (summary.passRate >= 95) {
      return {
        success: true,
        message: `所有核心功能测试通过 (${summary.passed}/${summary.total})`,
        details: summary,
      }
    } else {
      return {
        success: false,
        message: `部分测试失败 (${summary.passed}/${summary.total})`,
        details: summary,
      }
    }
  } catch (error) {
    return {
      success: false,
      message: `测试执行失败: ${error instanceof Error ? error.message : '未知错误'}`,
    }
  }
}
